// 1190. [栈dfs类似中序遍历]删除整个目录
// https://oj.rnd.huawei.com/problems/1190/details 中等
// 我们定义一种目录结构字符串(类似Windows的tree/f的输出内容)，用它来表达目录树的结构，如图所示：
// 目录结构字符串的输入仅含数字、字母和|-，其中：|-
// 表示子目录的层次符号；字母或数字表示目录名。
// 某目录的子目录的顺序以输入先后顺序为准。
// 某目录的多个子目录不能同名，如果出现多个，则只保留第一个，后续的输入忽略。
// 无对应的父目录，属于异常情况，直接忽略。
// 给定一个目录结构字符串，请按先后顺序删除所有目录，并依次输出删除的目录名称：
// 如果是叶子目录，直接删除。
// 如果某目录含有子目录，则需要先删除其子目录。
// 如上图所示的输出为C D F E B lib32 A
// 首行是一个整数 n，表示目录结构字符串的行数，取值范围 [1, 50)
// 接下来n行，每行字符串表示一个待处理的目录，目录名长度为[1,10]，整行字符串长度为
// [1,100]。 用例保证，有且仅有一个根目录。
// 输出字符串序列，表示依次删除的目录，目录之间以单空格分隔。

// 8
// A       root
// |-B
// |-|-C
// |-|-|-|-C
// |-|-B      ---不可清空 mapTree,同级单独处理
// |-|-|-B
// |-|-C
// |-B

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

//#define DEBUG
#ifdef DEBUG
#define PF(...) printf(__VA_ARGS__)
#else
#define PF(...)
#endif

class Solution {
 public:
  // 待实现函数，在此函数中填入答题代码;
  int deep(const string& str) {
    return std::count(str.begin(), str.end(), '-');
  }
  vector<string> DelAllDirectorys(const vector<string>& dirTreeLines) {
    vector<string> result;
    stack<string> stkNode;
    map<int, set<string> > mapTree;  //  <level, SET_dirName>
    for (auto curDirName : dirTreeLines) {
      int curNodeDepth = deep(curDirName);
      PF("new======= %d,%s\n", curNodeDepth, curDirName.c_str());
      // 同名已经存在
      if (mapTree[curNodeDepth].count(curDirName) > 0) {
        PF("pass, %s\n", curDirName.c_str());
        continue;
      }
      if (stkNode.empty() && curNodeDepth == 0) {
        PF("push=root, %d,%s\n", curNodeDepth, curDirName.c_str());
        stkNode.push(curDirName);
        mapTree[curNodeDepth].insert(curDirName);
        continue;
      }
      if (stkNode.empty()) {
        continue;
      }
      // 1.当前是上级，出栈
      // 2.当前是同级，出栈后进栈
      // 3.当前是[下一级]，进栈
      if (curNodeDepth <= deep(stkNode.top())) {
        while (!stkNode.empty() && curNodeDepth < deep(stkNode.top())) {
          string sTmpDir = stkNode.top();
          stkNode.pop();
          result.push_back(sTmpDir.substr(2 * deep(sTmpDir)));
          mapTree[deep(sTmpDir)].clear();
          PF("> %d. %d,[]clear.%s\n", deep(sTmpDir), curNodeDepth,
             sTmpDir.c_str());
        }
        string sTmpDir = stkNode.top();
        stkNode.pop();
        result.push_back(sTmpDir.substr(2 * deep(sTmpDir)));
        mapTree[curNodeDepth].insert(curDirName);  // 不能清空同级
        stkNode.push(curDirName);
      } else if (curNodeDepth == deep(stkNode.top()) + 1) {
        mapTree[curNodeDepth].insert(curDirName);
        stkNode.push(curDirName);
        PF("+1 %d.%d, [%d]%s\n", deep(stkNode.top()), curNodeDepth,
           mapTree[curNodeDepth].count(curDirName), curDirName.c_str());
      }
    }
    while (!stkNode.empty()) {
      string sTmpDir = stkNode.top();
      stkNode.pop();
      result.push_back(sTmpDir.substr(2 * deep(sTmpDir)));
      PF("tail %d. %s\n", deep(sTmpDir), sTmpDir.c_str());
    }
    PF("end\n");
    return result;
  }
};

// 以下为考题输入输出框架，此部分代码不建议改动
inline string ReadLine() {
  string line;
  getline(cin, line);
  return line;
}

inline vector<string> ReadLines(int size) {
  vector<string> lines(size);
  for (int i = 0; i < size; ++i) {
    lines[i] = ReadLine();
  }
  return lines;
}

inline vector<string> ReadCountedLines() {
  string numberLine = ReadLine();
  int count = stoi(numberLine);
  return ReadLines(count);
}

template <typename T>
inline void WriteVector(const vector<T>& objects, char delimeter = ' ') {
  auto it = objects.begin();
  if (it == objects.end()) {
    return;
  }
  cout << *it;
  for (++it; it != objects.end(); ++it) {
    cout << delimeter << *it;
  }
  cout << endl;
}

int main() {
  vector<string> dirTreeLines = ReadCountedLines();
  Solution solu;
  auto delDirs = solu.DelAllDirectorys(dirTreeLines);
  WriteVector(delDirs);

  return 0;
}
